/* This module implements miscellaneous peripherals for the cpu.

  1. Capabilities: One 32 bit word contains the capabilities of the bit file.
     PICO_STANDALONE_SW bit reflects whether an access from the PC-host has been received.
  2. Peekaboo. This port returns the last address accessed by the CPLD and is
     used to determine which image is currently loaded.
  3. Reboot port. When an address is written into this port the CPLD will set armed.
     The next access to flash ROM specifies the address for the CPLD to start at.

   Copyright 2007, Pico Computing, Inc.
   Robert Trout.
*/

`include "PicoDefines.v"

module PPC_FUNCTIONS
 (input  OPB_Clk,
  input  [31:0]OPB_ABus,    //PPC ->Slave signals
  input  [31:0]OPB_DBus,    //     "
  input  OPB_RNW,           //     "
  input  OPB_select,        //     "
  input  StandaloneSw,      //hrgt June 6, 07 added for standalone detection
  input  [25:0]FLASH_AIN,   //used to report peekaboo to PPC //hrgt: Jan 25, 07
  output [31:0]Sl_DBus,     //Slave -> OPB Signals
  output Sl_errAck,         //     "
  output Sl_retry,          //     "
  output Sl_toutSup,        //     "
  output Sl_xferAck,        //     "
  output CPLD_PEEKABOO_PPC, //Used to obtain the last address used before the FPGA successfully loaded. //hrgt: Jan 27, 07
  output CPLD_RELOAD_PPC    //Output triggers reload of FPGA by CPLD.                                   //hrgt: Jan 27, 07
 );

`define PEEKABOO_DELAY 2
///reg [31:0]             DebugRegister = 32'h5a5a5a5a;
reg [`PEEKABOO_DELAY-1:0] PeekabooDelay = `PEEKABOO_DELAY'h0;
reg                       armed         = 0;
wire   capsRead      = OPB_select & OPB_RNW & {OPB_ABus[31:2],  2'b0} == `OPB_CAPABILITIES;
//wire   debugRead     = OPB_select & OPB_RNW & {OPB_ABus[31:2],  2'b0} == `OPB_MISC_DEBUG;
wire debugRead     = 0;
wire   peekabooRead  = OPB_select & OPB_RNW & {OPB_ABus[31:2],  2'b0} == `OPB_PEEKABOO;
wire   rebootWrite   = OPB_select &~OPB_RNW & {OPB_ABus[31:2],  2'b0} == `OPB_REBOOT;
wire   flashAccess   = OPB_select & OPB_RNW & {OPB_ABus[31:28],28'b0} == `OPB_FLASH_BASEADDR;
assign Sl_retry      = 0;
assign Sl_errAck     = 0;
assign Sl_toutSup    = 0; 
assign Sl_xferAck    = capsRead | debugRead | PeekabooDelay[`PEEKABOO_DELAY-1];//hrgt: Jan 25, 07

assign Sl_DBus[31:0] = capsRead     ? 
                               (StandaloneSw ? (`IMAGE_CAPABILITIES |  `PICO_STANDALONE_SW)  //echo standalone sw
                                             : (`IMAGE_CAPABILITIES & ~`PICO_STANDALONE_SW)) :
                       peekabooRead ? {5'h0, FLASH_AIN[25:0], 1'b0}        //hrgt: Jan 25, 07
                                    : 0;
assign CPLD_PEEKABOO_PPC=peekabooRead;                        //Tristates Flash and activates CPLD peekaboo port.
                                                              //Will remain active until Sl_xferAck is asserted.
always @(posedge OPB_Clk) //hrgt: Jan 25, 07 for reload from cpu
   begin
   PeekabooDelay   <= {PeekabooDelay[`PEEKABOO_DELAY-2:0], peekabooRead}; 
   if (rebootWrite && OPB_DBus[7:0] == `CPLD_CONTROLLER_RELOAD_PASSWORD) //some elementary bullet proofing.
      armed        <= 1;                                      //arm for next access to flash
///if (flashAccess & armed) DebugRegister<= OPB_ABus;         //visible to monitor (for debugging)
   end

//Software will access flash ROM address. If armed is set following triggers CPLD.
assign CPLD_RELOAD_PPC = armed & flashAccess;
endmodule
